/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "dma.h"
#include "iwdg.h"
#include "spi.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include "Inf_W5500_Ping.h"
#include "httpServer.h"
#include "webpage.h"
#include "W25Q64.h"
#include "TypeDefine.h"
#include "Mod_NetConfig.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
//#define MAX_HTTPSOCK	2
//定义socket端口5~7,为http server使用
uint8_t socknumlist[] = { 5, 6, 7 };
#define DATA_BUF_SIZE 2048
uint8_t RX_BUF[DATA_BUF_SIZE];
uint8_t TX_BUF[DATA_BUF_SIZE];
/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_SPI2_Init();
  MX_UART4_Init();
  MX_UART5_Init();
  MX_USART2_UART_Init();
  MX_USART1_UART_Init();
  MX_IWDG_Init();
  MX_USART3_UART_Init();
  MX_SPI1_Init();
  /* USER CODE BEGIN 2 */
	 
   // 初始化结构体
//   NetCfg_TypeDef NetconfigWrite = {
//    .auch_SIP = {192, 168, 58, 111},  // IP 地址
//    .auch_GA = {192, 168, 58, 1},     // 网关地址
//    .auch_SUB = {255, 255, 255, 0},   // 子网掩码
//    .auch_SHA = {0x00, 0x1A, 0x2B, 0x3C, 0x4D, 0x5E}, // MAC 地址
//    .uin_RTR = 5000,                  // 重试超时时间（单位：毫秒）
//    .uch_RCR = 3,                       // 重试次数
//		.auch_DNS = {114, 114, 114, 114}	
//     };
	
		//NetworkConfig_Write(NetconfigWrite);
	 
//	  SocketConfig SocktconfigWrite = 
//	  {
//	 		 .server_ip={192,168,58,254},
//	 		 .port0=40001,
//	 		 .port1=40001,
//	 		 .port2=40001,
//	 		 .port3=40001,
//       .port4=40001,
//	 		 .port5=40001,
//			 .localport0=40000,  
//			 .localport1=40001,
//			 .localport2=40002,
//			 .localport3=40003,
//			 .localport4=40004,
//			 .localport5=40005,
//			 
//	  };
		 
		//SocketConfig_Write(configWrite);
     		
		
		
//		SocketConfig configRead=SocketCfg_Read();
//		printf("Read IP: %d.%d.%d.%d \n",
//								configRead.server_ip[0],
//		            configRead.server_ip[1],
//		            configRead.server_ip[2],
//		            configRead.server_ip[3]) ;
//		
//	  printf("Port0 is : %d\n", configRead.port0);
//		printf("Port1 is : %d\n", configRead.port1);
//		printf("Port2 is : %d\n", configRead.port2);
//		printf("Port3 is : %d\n", configRead.port3);
//    printf("Port5 is : %d\n", configRead.port5);
//		
//		printf("LocalPort0 is : %d\n", configRead.localport0);
//		printf("LocalPort1 is : %d\n", configRead.localport1);
//		printf("LocalPort2 is : %d\n", configRead.localport2);
//		printf("LocalPort3 is : %d\n", configRead.localport3);
//    printf("LocalPort5 is : %d\n", configRead.localport5);
//		
	 
//	 printf("Writing size: %lu bytes\n", sizeof(rem_configWrite)); // 应该是 24 字节
//	 // 写入数据
//   RemoteNetworkConfig_Write(rem_configWrite);     
	 //W25Q64_ReadData(0x081000, (uint8_t*)&rem_configRead, sizeof(RemotNetCfg_TypeDef));		//读取刚写入的测试数据到读取数据的测试数组�?
		

	//NetCfg_TypeDef NetconfigRead=NetworkConfig_Read();
	// 打印读取结果
  //printNetConfig(&localnet_config);




	//先读取设备中网络配置信息再初始化
	Forward_Init();
	printf("Forward_Init success\r\n");
  //PingInit主要用于httpServer,放在ForwardInit之后获取网络配置信息	
	Inf_W5500_Ping_Init();
	printf("Inf_W5500_Ping_Init success\r\n");
	
	HttpServer_Init();

  printNetConfig(&localnet_config);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    Forward_Task();
		HttpServer_Task();
    HAL_IWDG_Refresh(&hiwdg);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
